<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>YAML工具</title>
    <style>
        /* 基础样式重置 */
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        
        /* CSS变量定义 */
        :root {
            --primary-color: #3498db;
            --primary-hover: #2980b9;
            --secondary-color: #95a5a6;
            --secondary-hover: #7f8c8d;
            --background-color: #f4f4f4;
            --card-background: #ffffff;
            --text-color: #333333;
            --border-color: #dddddd;
            --border-radius: 5px;
            --box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
            --font-family: Arial, sans-serif;
            --monospace-font: 'Courier New', monospace;
            --gap: 20px;
        }
        
        body {
            font-family: var(--font-family);
            background-color: var(--background-color);
            color: var(--text-color);
            margin: 0;
            padding: 20px;
        }
        
        .container {
            max-width: 95%;
            margin: 0 auto;
        }
        
        /* 头部样式 */
        header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 20px;
        }
        
        h1 {
            color: #2c3e50;
            font-size: 24px;
        }
        
        .back-btn {
            background-color: var(--primary-color);
            color: white;
            padding: 10px 20px;
            text-decoration: none;
            border-radius: var(--border-radius);
            transition: background-color 0.3s ease;
        }
        
        .back-btn:hover {
            background-color: var(--primary-hover);
        }
        
        /* 工具卡片样式 */
        .tool-card {
            background-color: var(--card-background);
            padding: 20px;
            border-radius: 8px;
            box-shadow: var(--box-shadow);
        }
        
        /* 按钮组样式 */
        .btn-group {
            display: flex;
            gap: 10px;
            margin-bottom: 20px;
            flex-wrap: wrap;
        }
        
        .btn {
            background-color: var(--primary-color);
            color: white;
            border: none;
            padding: 10px 20px;
            border-radius: var(--border-radius);
            cursor: pointer;
            font-size: 14px;
            transition: background-color 0.3s ease;
        }
        
        .btn:hover {
            background-color: var(--primary-hover);
        }
        
        .btn:active {
            transform: translateY(1px);
        }
        
        .btn-secondary {
            background-color: var(--secondary-color);
        }
        
        .btn-secondary:hover {
            background-color: var(--secondary-hover);
        }
        
        /* 输入输出容器样式 */
        .io-container {
            display: flex;
            gap: 20px;
            align-items: flex-start;
        }
        
        .io-panel {
            flex: 1;
            min-width: 0;
        }
        
        .io-header {
            font-weight: bold;
            margin-bottom: 10px;
            color: #555;
        }
        
        /* 文本区域样式 */
        .textarea-wrapper {
            position: relative;
            height: 500px;
        }
        
        /* 行号容器样式 */
        .lined-area {
            position: relative;
            display: flex;
            width: 100%;
            height: 100%;
            overflow: hidden;
        }
        
        /* 行号区域样式 */
        .line-numbers {
            background-color: #f0f0f0;
            color: #808080;
            text-align: right;
            padding: 15px 8px;
            border-right: 1px solid #ddd;
            user-select: none;
            font-family: var(--monospace-font);
            font-size: 14px;
            line-height: 1.5;
            overflow: hidden;
            min-width: 40px;
            white-space: pre;
        }
        
        /* 内容区域样式 */
        .content-area {
            flex: 1;
            padding: 15px;
            overflow: auto;
            font-family: var(--monospace-font);
            font-size: 14px;
            line-height: 1.5;
            background-color: #fafafa;
        }
        
        /* 高亮区域样式 */
        .highlighted-content {
            margin: 0;
        }
        
        /* 文本区域容器 */
        .textarea-container {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            box-sizing: border-box;
        }
        
        textarea {
            width: 100%;
            height: 100%;
            padding: 15px 15px 15px 58px;
            border: 1px solid var(--border-color);
            border-radius: var(--border-radius);
            font-family: var(--monospace-font);
            font-size: 14px;
            resize: vertical;
            line-height: 1.5;
            overflow: auto;
            box-sizing: border-box;
        }
        
        /* 交换按钮样式 */
        .swap-container {
            display: flex;
            justify-content: center;
            align-items: center;
            padding: 10px;
        }
        
        .swap-btn {
            width: 50px;
            height: 50px;
            border-radius: 50%;
            font-size: 20px;
            display: flex;
            justify-content: center;
            align-items: center;
            padding: 0;
            cursor: pointer;
            transition: all 0.3s ease;
        }
        
        .swap-btn:hover {
            transform: scale(1.1);
        }
        
        /* 底部操作按钮样式 */
        .action-buttons {
            display: flex;
            justify-content: center;
            gap: 10px;
            margin-top: 20px;
        }
        
        /* YAML语法高亮样式 */
        .yaml-key {
            color: #0000ff;
        }
        
        .yaml-string {
            color: #006400;
        }
        
        .yaml-number {
            color: #a31515;
        }
        
        .yaml-boolean {
            color: #0000ff;
        }
        
        .yaml-null {
            color: #808080;
        }
        
        .yaml-comment {
            color: #808080;
            font-style: italic;
        }
        
        .yaml-list-item {
            color: #0000ff;
        }
        
        /* 响应式设计 */
        @media (max-width: 768px) {
            .io-container {
                flex-direction: column;
            }
            
            .btn-group {
                flex-direction: column;
            }
            
            .textarea-wrapper {
                height: 300px;
            }
            
            textarea,
            .highlighted-area {
                height: 100%;
            }
            
            .swap-container {
                padding: 10px 0;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <header>
            <h1>YAML工具</h1>
            <a href="index.html" class="back-btn">返回主页</a>
        </header>
        
        <div class="tool-card">
            <!-- 工具按钮组 -->
            <div class="btn-group">
                <button class="btn" onclick="compressYAML()">压缩YAML</button>
                <button class="btn" onclick="formatYAML()">格式化YAML</button>
                <button class="btn" onclick="compressAndEscapeYAML()">压缩并添加转义字符</button>
                <button class="btn" onclick="unescapeYAML()">去转义字符</button>
                <button class="btn" onclick="unescapeAndFormatYAML()">去转义并格式化</button>
            </div>
            
            <!-- 输入输出区域 -->
            <div class="io-container">
                <!-- 输入区域 -->
                <div class="io-panel">
                    <div class="io-header">输入YAML：</div>
                    <div class="textarea-wrapper">
                        <textarea id="inputArea" placeholder="请输入YAML内容..."></textarea>
                    </div>
                </div>
                
                <!-- 交换按钮 -->
                <div class="swap-container">
                    <button class="btn swap-btn" onclick="swapInputOutput()">⇄</button>
                </div>
                
                <!-- 输出区域 -->
                <div class="io-panel">
                    <div class="io-header" style="display: flex; justify-content: space-between; align-items: center;">
                        输出结果：
                        <button class="btn btn-secondary" style="padding: 5px 10px; font-size: 12px;" onclick="copyResult()">复制</button>
                    </div>
                    <div class="textarea-wrapper">
                        <!-- 文本区域容器 -->
                        <div id="outputTextAreaContainer" class="textarea-container">
                            <textarea id="outputArea" readonly placeholder="处理结果将显示在这里..."></textarea>
                        </div>
                        <!-- 带行号的高亮区域 -->
                        <div id="highlightedArea" class="lined-area" style="display: none;">
                            <div id="lineNumbers" class="line-numbers"></div>
                            <div class="content-area">
                                <pre id="highlightedContent" class="highlighted-content"></pre>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
            
            <!-- 底部操作按钮 -->
            <div class="action-buttons">
                <button class="btn btn-secondary" onclick="copyResult()">复制结果</button>
                <button class="btn btn-secondary" onclick="clearAll()">清空所有</button>
            </div>
        </div>
    </div>
    
    <script>
        // 通用函数：交换输入输出
        function swapInputOutput() {
            const input = document.getElementById('inputArea');
            const output = document.getElementById('outputArea');
            const highlighted = document.getElementById('highlightedArea');
            
            const temp = input.value;
            input.value = output.value;
            updateOutput(output.value);
            output.value = temp;
        }
        
        // 通用函数：复制结果
        function copyResult() {
            const output = document.getElementById('outputArea');
            output.select();
            
            try {
                if (navigator.clipboard && window.isSecureContext) {
                    navigator.clipboard.writeText(output.value).then(() => {
                        alert('结果已复制到剪贴板');
                    }).catch(err => {
                        document.execCommand('copy');
                        alert('结果已复制到剪贴板');
                    });
                } else {
                    document.execCommand('copy');
                    alert('结果已复制到剪贴板');
                }
            } catch (err) {
                alert('复制失败，请手动复制内容');
            }
        }
        
        // 通用函数：清空所有
        function clearAll() {
            document.getElementById('inputArea').value = '';
            updateOutput('');
        }
        
        // 生成行号
        function generateLineNumbers(content) {
            const lines = content.split('\n');
            let lineNumbers = '';
            for (let i = 1; i <= lines.length; i++) {
                lineNumbers += i + '\n';
            }
            return lineNumbers;
        }
        
        // 通用函数：更新输出结果
        function updateOutput(content) {
            const outputArea = document.getElementById('outputArea');
            const outputTextAreaContainer = document.getElementById('outputTextAreaContainer');
            const highlightedArea = document.getElementById('highlightedArea');
            const lineNumbers = document.getElementById('lineNumbers');
            const highlightedContent = document.getElementById('highlightedContent');
            
            outputArea.value = content;
            
            if (content) {
                // 显示高亮结果，隐藏textarea
                const highlighted = highlightYAML(content);
                
                // 生成行号
                const lines = content.split('\n');
                let lineNumbersText = '';
                for (let i = 1; i <= lines.length; i++) {
                    lineNumbersText += i + '\n';
                }
                lineNumbers.textContent = lineNumbersText;
                
                // 更新高亮内容
                highlightedContent.innerHTML = highlighted;
                
                // 确保高亮区域和行号区域的高度一致
                highlightedContent.style.height = 'auto';
                lineNumbers.style.height = 'auto';
                
                // 显示高亮区域，隐藏textarea
                outputTextAreaContainer.style.display = 'none';
                highlightedArea.style.display = 'flex';
            } else {
                // 显示textarea，隐藏高亮结果
                outputTextAreaContainer.style.display = 'block';
                highlightedArea.style.display = 'none';
            }
        }
        
        // YAML语法高亮函数
        function highlightYAML(yaml) {
            if (!yaml) return '';
            
            // 创建临时元素用于安全转义
            const tempDiv = document.createElement('div');
            tempDiv.textContent = yaml;
            let escapedYaml = tempDiv.innerHTML;
            
            // 高亮注释
            escapedYaml = escapedYaml.replace(/(^\s*#.*$)/gm, '<span class="yaml-comment">$1</span>');
            
            // 高亮列表项
            escapedYaml = escapedYaml.replace(/(^\s*[-]\s+)/gm, '<span class="yaml-list-item">$1</span>');
            
            // 高亮键值对中的键
            escapedYaml = escapedYaml.replace(/(^\s*[^:#\s]+)(:\s*)/gm, '<span class="yaml-key">$1</span>$2');
            
            // 高亮字符串值
            escapedYaml = escapedYaml.replace(/(:\s*)(".*?")/gm, '$1<span class="yaml-string">$2</span>');
            escapedYaml = escapedYaml.replace(/(:\s*)('.*?')/gm, '$1<span class="yaml-string">$2</span>');
            
            // 高亮数字值
            escapedYaml = escapedYaml.replace(/(:\s*)(-?\d+(\.\d+)?)/gm, '$1<span class="yaml-number">$2</span>');
            
            // 高亮布尔值
            escapedYaml = escapedYaml.replace(/(:\s*)(true|false)/gm, '$1<span class="yaml-boolean">$2</span>');
            
            // 高亮null值
            escapedYaml = escapedYaml.replace(/(:\s*)(null|None)/gm, '$1<span class="yaml-null">$2</span>');
            
            return escapedYaml;
        }
        
        // YAML格式化函数
        function formatYAML() {
            const input = document.getElementById('inputArea').value;
            if (!input) {
                alert('请输入YAML内容');
                return;
            }
            
            let formatted = '';
            let indent = 0;
            const stack = [0]; // 用于跟踪缩进级别
            
            // 按行处理
            const lines = input.split('\n');
            
            for (let i = 0; i < lines.length; i++) {
                const line = lines[i];
                const trimmedLine = line.trim();
                
                // 跳过空行
                if (trimmedLine === '') {
                    formatted += '\n';
                    continue;
                }
                
                // 处理注释
                if (trimmedLine.startsWith('#')) {
                    formatted += '  '.repeat(indent) + trimmedLine + '\n';
                    continue;
                }
                
                // 计算当前行的缩进
                const currentIndent = line.match(/^\s*/)[0].length;
                const currentIndentLevel = Math.floor(currentIndent / 2);
                
                // 更新缩进级别
                if (currentIndentLevel < stack[stack.length - 1]) {
                    // 减少缩进
                    while (stack.length > 0 && stack[stack.length - 1] > currentIndentLevel) {
                        stack.pop();
                    }
                    indent = stack[stack.length - 1];
                }
                
                // 处理列表项
                if (trimmedLine.startsWith('- ')) {
                    formatted += '  '.repeat(indent) + trimmedLine + '\n';
                    
                    // 检查下一行是否是嵌套内容
                    if (i + 1 < lines.length) {
                        const nextLine = lines[i + 1];
                        const nextTrimmed = nextLine.trim();
                        if (nextTrimmed && !nextTrimmed.startsWith('#')) {
                            const nextIndent = nextLine.match(/^\s*/)[0].length;
                            if (nextIndent > currentIndent) {
                                stack.push(indent + 1);
                                indent = indent + 1;
                            }
                        }
                    }
                    continue;
                }
                
                // 处理键值对
                const colonIndex = trimmedLine.indexOf(':');
                if (colonIndex !== -1) {
                    const key = trimmedLine.substring(0, colonIndex).trim();
                    let value = trimmedLine.substring(colonIndex + 1).trim();
                    
                    // 处理嵌套对象
                    if (value === '') {
                        formatted += '  '.repeat(indent) + `${key}:\n`;
                        
                        // 检查下一行是否是嵌套内容
                        if (i + 1 < lines.length) {
                            const nextLine = lines[i + 1];
                            const nextTrimmed = nextLine.trim();
                            if (nextTrimmed && !nextTrimmed.startsWith('#')) {
                                const nextIndent = nextLine.match(/^\s*/)[0].length;
                                if (nextIndent > currentIndent) {
                                    stack.push(indent + 1);
                                    indent = indent + 1;
                                }
                            }
                        }
                    } else {
                        formatted += '  '.repeat(indent) + `${key}: ${value}\n`;
                    }
                    continue;
                }
                
                // 处理普通文本
                formatted += '  '.repeat(indent) + trimmedLine + '\n';
            }
            
            updateOutput(formatted.trim());
        }
        
        // YAML压缩函数
        function compressYAML() {
            const input = document.getElementById('inputArea').value;
            if (!input) {
                alert('请输入YAML内容');
                return;
            }
            
            // 压缩YAML：移除多余的空格和换行，但保留必要的结构
            let compressed = input
                .split('\n')
                .map(line => line.trim())
                .filter(line => line !== '' && !line.startsWith('#'))
                .join(' ');
            
            // 移除多余的空格
            compressed = compressed.replace(/\s+/g, ' ').trim();
            
            updateOutput(compressed);
        }
        
        // 压缩并添加转义字符
        function compressAndEscapeYAML() {
            const input = document.getElementById('inputArea').value;
            if (!input) {
                alert('请输入YAML内容');
                return;
            }
            
            // 先去转义
            const unescaped = input
                .replace(/\\"/g, '"')
                .replace(/\\'/g, "'")
                .replace(/\\\\/g, '\\');
            
            // 压缩YAML
            let compressed = unescaped
                .split('\n')
                .map(line => line.trim())
                .filter(line => line !== '' && !line.startsWith('#'))
                .join(' ');
            
            // 移除多余的空格
            compressed = compressed.replace(/\s+/g, ' ').trim();
            
            // 添加斜杠转义字符（只转义单引号、双引号和反斜杠）
            const escaped = compressed
                .replace(/\\/g, '\\\\')
                .replace(/"/g, '\\"')
                .replace(/'/g, "\\'");
            
            updateOutput(escaped);
        }
        
        // 去转义字符
        function unescapeYAML() {
            const input = document.getElementById('inputArea').value;
            if (!input) {
                alert('请输入YAML内容');
                return;
            }
            
            const unescaped = input
                .replace(/\\"/g, '"')
                .replace(/\\'/g, "'")
                .replace(/\\\\/g, '\\');
            
            updateOutput(unescaped);
        }
        
        // 去转义并格式化
        function unescapeAndFormatYAML() {
            const input = document.getElementById('inputArea').value;
            if (!input) {
                alert('请输入YAML内容');
                return;
            }
            
            // 先去转义
            const unescaped = input
                .replace(/\\"/g, '"')
                .replace(/\\'/g, "'")
                .replace(/\\\\/g, '\\');
            
            // 设置输入内容为去转义后的内容，然后调用格式化函数
            document.getElementById('inputArea').value = unescaped;
            formatYAML();
        }
    </script>
</body>
</html>